package com.gopay.checkorder.service.impl.expay;

import java.math.BigDecimal;
import java.util.List;

import javax.annotation.Resource;

import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.gopay.checkorder.service.BankOrderService;
import com.gopay.checkorder.service.task.BankCountDownLatch;
import com.gopay.common.Result;
import com.gopay.common.constants.bank.BankConstants;
import com.gopay.common.constants.bank.BisBankBusinessProd;
import com.gopay.common.constants.bank.BisBankInterfaceChannel;
import com.gopay.common.constants.bank.CebContants;
import com.gopay.common.constants.proccode.ProcCodeConstants;
import com.gopay.common.domain.bank.BankOrder;
import com.gopay.common.domain.bank.BaseMessage;
import com.gopay.common.domain.bank.ceb.expay.CebExPayMessage;
import com.gopay.common.domain.bank.ceb.expay.res.CebExPayMessageNSOQRes;
import com.gopay.common.domain.bank.dayend.BaseDayendEntry;
import com.gopay.common.domain.cashier.BankCardType;
import com.gopay.common.domain.cps.vo.CheckOrderResult;
import com.gopay.common.domain.cps.vo.InAccInfo;
import com.gopay.remote.bank.ExPayInteractRemoteService;

public class CheckOrderCebExPayImpl implements BankOrderService {

    private final static Logger logger = LoggerFactory.getLogger("CEB");

    @Resource(name = "bankExPayClient")
    private ExPayInteractRemoteService bankExPayClient;

   @Override
   public CheckOrderResult checkOrder(BankOrder bankOrder, String target) {
       CheckOrderResult checkOrderResult = new CheckOrderResult();
       checkOrderResult.setSuccess(false);
       checkOrderResult.setOrderId(bankOrder.getOrderId());

       CebExPayMessage base = new CebExPayMessage();
       base.setOrderId(bankOrder.getOrderId());
       base.setBankOrderId(bankOrder.getOutOrderId());
       base.setBank(BankConstants.BANK_LOGO_CEB);
       base.setBankIntrChann(BisBankInterfaceChannel.get(bankOrder.getInterfaceChennelCode()));
       base.setBankBusProd(BisBankBusinessProd.get(bankOrder.getBankBizProdCode()));
       
       Result result = new Result();
       try {
           result = bankExPayClient.queryOrder(base);
           if (result == null || !result.isSuccess()) {
               logger.error("bankClient fail.");
               if(result ==null || ProcCodeConstants.PROC_CODE_100E6037.equals(result.getResultCode())){
                   BankCountDownLatch.failIncrease(bankOrder.getBankCode());
               }
               logger.error(ToStringBuilder.reflectionToString(result,ToStringStyle.DEFAULT_STYLE));
               checkOrderResult.setErrCode(ProcCodeConstants.PROC_CODE_100E6022);
               checkOrderResult.setErrMsg("系统返回对账结果为空");
               return checkOrderResult;
           }
           if(StringUtils.isNotBlank(result.getBankRetCode())){
               //add by liuyu, 20170803, 快捷API失败通知
               bankOrder.setBankRespCode(result.getBankRetCode());
           }

           CebExPayMessageNSOQRes res = (CebExPayMessageNSOQRes) result.getDefaultModel();
           if (res == null) {
               // 查询订单为空
               logger.error("fail:orderId:" + bankOrder.getOrderId()+ " errcode:" + ProcCodeConstants.PROC_CODE_100E5062+ " err:bis query is null.");
               checkOrderResult.setErrCode(ProcCodeConstants.PROC_CODE_100E5062);
               checkOrderResult.setErrMsg("银行返回对账结果为空");
           }

           // 如果查询成功，则一定有定单信息
           else {
               // 成功处理
               if (CebContants.EXPAY_QUERY_RESP_STATUS_SUCCESS.equals(res.getStatus())) {// 如果成功
                   checkOrderResult.setSuccess(true);
                   InAccInfo accInfo = new InAccInfo();
                   accInfo.setOrderId(res.getSerialNo());  
                   accInfo.setAmount(new BigDecimal(res.getAmount()));
                   accInfo.setRetCode("00");
                   accInfo.setCardType(BankCardType.Unknown.toString());
                   checkOrderResult.setAccInfo(accInfo);
                   logger.error("光大快捷支付订单：" + bankOrder.getOrderId() + "，交易状态为："+ CebContants.EXPAY_QUERY_RESP_STATUS_SUCCESS + "，支付成功。");
               }
               //处理中
               else if (CebContants.EXPAY_QUERY_RESP_STATUS_DEALING.equals(res.getStatus())) {// 如果处理中
                   checkOrderResult.setErrMsg("银行返回处理中");
                   logger.error("光大快捷支付订单：" + bankOrder.getOrderId() + "交易状态为："+ CebContants.EXPAY_QUERY_RESP_STATUS_DEALING + "，交易处理中。");
               }
               //处理中
               else if (CebContants.EXPAY_QUERY_RESP_STATUS_NOORDER.equals(res.getStatus())) {// 银行查无订单
                   checkOrderResult.setErrMsg("银行返回找不到订单");
                   logger.error("光大快捷支付订单：" + bankOrder.getOrderId() + "交易状态为："+ CebContants.EXPAY_QUERY_RESP_STATUS_NOORDER + "，银行查无此订单。");
               }
               //失败处理
               else if (CebContants.EXPAY_QUERY_RESP_STATUS_FAILED.equals(res.getStatus())) {// 如果失败
                   InAccInfo accInfo = new InAccInfo();
                   accInfo.setOrderId(res.getSerialNo());
                   accInfo.setAmount(new BigDecimal(res.getAmount()));
                   accInfo.setRetCode("01");
                   accInfo.setCardType(BankCardType.Unknown.toString());
                   checkOrderResult.setAccInfo(accInfo);
                   checkOrderResult.setBankFailure(true);
                   logger.error("光大快捷支付订单：" + bankOrder.getOrderId() + "交易状态为："+ CebContants.EXPAY_QUERY_RESP_STATUS_FAILED + "，交易失败。");
                   checkOrderResult.setErrMsg("银行返回失败");
               }
           }

           return checkOrderResult;
           
       } catch (Exception e) {
           logger.error("bankExPayClient fail.", e);
           checkOrderResult.setErrCode(ProcCodeConstants.PROC_CODE_100E6022);
           checkOrderResult.setErrMsg("对账调用bis失败");
           return checkOrderResult;
       }
   }


   @Override
   public BankOrder getDbOrder() {
       // TODO Auto-generated method stub
       return null;
   }

   @Override
   public BaseMessage dayend(String bank_bus) {
       // TODO Auto-generated method stub
       return null;
   }

   @Override
   public Result getDayendMsg(String string) {
       // TODO Auto-generated method stub
       return null;
   }

   @Override
   public List<CheckOrderResult> checkDayend(String bank_bus) {
       // TODO Auto-generated method stub
       return null;
   }

   @Override
   public CheckOrderResult checkDayendOrder(BaseDayendEntry bdm, BankOrder bo) {
       // TODO Auto-generated method stub
       return null;
   }

}
